import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import model.AirPlane;
import model.Employee;
import model.Fly;
import model.FlyEmployee;
import model.Location;
import model.Stay;
import model.enums.FlyStayType;
import model.enums.StayType;

import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;

/**
 * Хуваарь табын контроллер класс
 * 
 * @author Энхтөр Энхтөр
 * @version 1.0
 * @since 2012-01-27
 */
public class MainController extends Controller
{

	private static final long	serialVersionUID	= -1675004750584223439L;

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
	{
		super.doGet(request, response);
	}

	public void index(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
	{
		String html = getViewHtml("main", "index");
		html = html.replaceAll("\\{path\\}", StaticMethods.PATH);
		String role = request.getSession().getAttribute("role").toString();
		html = html.replaceAll("\\{role\\}", role);
		renderView(html, response);
	}

	public void main(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
	{
		String tabs1_html = getViewHtml("main/tabs1", "tabs1");
		tabs1_html = tabs1_html.replaceAll("\\{year\\_list\\}", getYearList());

		SimpleDateFormat sdfYear = new SimpleDateFormat("yyyy");
		SimpleDateFormat sdfMonth = new SimpleDateFormat("MM");
		int currentYear = Integer.parseInt(sdfYear.format(new Date()));
		int currentMonth = Integer.parseInt(sdfMonth.format(new Date()));

		tabs1_html = tabs1_html.replaceAll("\\{tabs1\\_table\\}", setTableHtml(getSession(), currentYear, currentMonth));
		renderView(tabs1_html, response);
	}

	public void generate(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
	{
		Transaction transaction = getSession().beginTransaction();

		String stringQuery = "DELETE FROM FlyEmployee";
		Query query = getSession().createQuery(stringQuery);
		query.executeUpdate();

		transaction.commit();
		// INITIALIZE MODE
		long averageHour = Calculate.gen(getSession(), Calculate.GENERATE_MODE_INITIALIZE, Employee.EMPLOYEE_CATEGORY_STEWARDS, false, 0);
		Calculate.gen(getSession(), Calculate.GENERATE_MODE_INITIALIZE, Employee.EMPLOYEE_CATEGORY_SENIOR_STEWARDS, true, averageHour);
		Calculate.gen(getSession(), Calculate.GENERATE_MODE_INITIALIZE, Employee.EMPLOYEE_CATEGORY_SENIOR_ASSIST_STEWARDS, true, averageHour);
		// FILL MODE
		// Calculate.gen(getSession(), Calculate.GENERATE_MODE_FILL,
		// Employee.EMPLOYEE_CATEGORY_SENIOR_STEWARDS, false, 0);
		// Calculate.gen(getSession(), Calculate.GENERATE_MODE_FILL,
		// Employee.EMPLOYEE_CATEGORY_SENIOR_ASSIST_STEWARDS, false, 0);
		index(request, response);
	}

	public void clear(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
	{
		Transaction transaction = getSession().beginTransaction();

		String stringQuery = "DELETE FROM FlyEmployee";
		Query query = getSession().createQuery(stringQuery);
		query.executeUpdate();

		transaction.commit();
		index(request, response);
	}

	public String setTableHtml(Session session, int year, int month)
	{
		int calendarMonth = month - 1;// For Calendar.FEBRUARY etc
		int limit_column = StaticMethods.getDayOfMonth(year, calendarMonth);
		StringBuilder fixed_tabs1_html = new StringBuilder();
		fixed_tabs1_html.append("<table id=\"schedule\" cellpadding=\"0\" cellspacing=\"0\">");
		fixed_tabs1_html.append(getHeader(year, calendarMonth));
		for (String hour : getAllHour())
		{
			fixed_tabs1_html.append("<tr id=\"text\"><td>" + hour + "</td>");
			for (int day = 1; day <= limit_column; day++)
			{
				ArrayList<Fly> flies = Fly.getFliesListByThisMonth(session);
				boolean isFound = false;
				Fly foundedFly = null;
				for (Fly fly : flies)
				{
					Date flyDate = fly.getDate1();
					Calendar calendar = Calendar.getInstance();
					calendar.setTime(flyDate);
					int flyDay = calendar.get(Calendar.DAY_OF_MONTH);
					SimpleDateFormat sdf = new SimpleDateFormat("MM");
					int flyMonth = Integer.parseInt(sdf.format(flyDate));
					sdf = new SimpleDateFormat("yyyy");
					int flyYear = Integer.parseInt(sdf.format(flyDate));
					String flyHour = StaticMethods.getFormattedDateForHourAndMin(flyDate);
					if ( flyDay == day && flyHour.equals(hour) && flyMonth == month && flyYear == year )
					{
						isFound = true;
						foundedFly = fly;
						break;
					}
				}
				if ( isFound )
				{
					fixed_tabs1_html.append(getFlyDetailHtml(session, foundedFly));
				}
				else
				{
					fixed_tabs1_html.append("<td class=\"box-none\"></td>");
				}
			}
			fixed_tabs1_html.append("</tr>");
		}
		fixed_tabs1_html.append("</table>");
		return fixed_tabs1_html.toString();
	}

	private String getHeader(int year, int month)
	{
		int days = StaticMethods.getDayOfMonth(year, month);
		StringBuilder header = new StringBuilder();
		header.append("<tr id=\"title\">");
		header.append("<td width=\"100px\">Цагууд</td>");
		for (int day = 1; day <= days; day++)
		{
			Calendar calendar = Calendar.getInstance();
			calendar.set(year, month, day);
			header.append("<td width=\"70px\"><div>" + day + "</div><div>" + StaticMethods.getDayName(calendar) + "</div></td>");
		}
		header.append("</tr>");
		return header.toString();
	}

	public static String getFlyDetailHtml(Session session, Fly fly)
	{
		String result = Fly.checkFly(session, fly);
		StringBuilder detailHtml = new StringBuilder();
		detailHtml.append("<td class=\"box " + (result.length() == 0 ? "" : "alert") + "\" id=\"box\" flyid=\"" + fly.getId() + "\">");
		detailHtml.append("		<div>");
		detailHtml.append("			<div>" + Fly.getFlyName(session, fly, 1, false) + "</div>");
		detailHtml.append("			<div>" + AirPlane.getAirPlaneMark(session, fly.getAirPlane()) + "</div>");
		detailHtml.append("			<div style=\"align:left; margin:5px 0; border-top:1px solid #CCC\"></div>");
		detailHtml.append("			" + getEmployeesForDetail(fly, session));
		detailHtml.append("		</div>");
		detailHtml.append("</td>");
		// popup alert
		if ( result.length() != 0 )
		{
			detailHtml.append("<div class=\"alert_pop\" id=\"alert_pop"+fly.getId()+"\">" + result + "</div>");
		}
		return detailHtml.toString();
	}

	public static String getEmployeesForDetail(Fly fly, Session session)
	{
		String popup = "";
		int count = 1;
		for (Employee employee : Employee.getEmployeesByFly(session, fly))
		{
			popup += "<div style=\"display:inline-block; width:100%\">";
			popup += "<div style=\"float:left; width:6px;  margin:0 3px\"></div>";
			popup += "<div style=\"float:left; background-color:" + getEmployeeBgColor(employee) + ";\"><span>" + count + "." + employee.getName(true) + "</span></div>";
			popup += "</div>";
			count++;
		}
		return popup;
	}

	public static String getEmployeeBgColor(Employee employee)
	{
		switch (employee.getCategory())
		{
			case Employee.EMPLOYEE_CATEGORY_SENIOR_STEWARDS:
				return "#ffd9d9";
			case Employee.EMPLOYEE_CATEGORY_SENIOR_ASSIST_STEWARDS:
				return "#e6d9ff";
			case Employee.EMPLOYEE_CATEGORY_STEWARDS:
				return "#d6ffd8";
			default:
				return "";
		}
	}

	public ArrayList<String> getAllHour()
	{
		ArrayList<String> hours = new ArrayList<String>();
		ArrayList<Fly> allFlies = Fly.getFliesListByThisMonth(getSession());
		for (Fly fly : allFlies)
		{
			String flyHour = StaticMethods.getFormattedDateForHourAndMin(fly.getDate1());
			if ( !hours.contains(flyHour) )
			{
				hours.add(flyHour);
			}
		}
		Collections.sort(hours);
		return hours;
	}

	/**
	 * 
	 * @param request
	 * @param response
	 * @throws ServletException
	 * @throws IOException
	 * 
	 *             Нислэг дээр дарах үед ажаксаар дуудагдаж байгаа.
	 */
	public void getPopup(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
	{
		long flyid = Long.parseLong(request.getParameter("flyid"));
		Fly fly = (Fly) getObjectByPk(Fly.class, flyid);
		String popup = getViewHtml("main", "dialog");

		popup = popup.replaceAll("\\{fly\\_name\\_and\\_time\\}", Fly.getFlyName(getSession(), fly, 1, false) + " " + StaticMethods.getFormattedDateForHourAndMin(fly.getDate1()));
		popup = popup.replaceAll("\\{plane\\}", fly.getAirPlane().getMark());
		popup = popup.replaceAll("\\{employee\\_list\\}", getEmployees(request, response));
		popup = popup.replaceAll("\\{available\\_employee\\_list\\}", getAvailableEmployeeList(fly, getSession()));
		popup = popup.replaceAll("\\{fly\\_id\\}", fly.getId() + "");
		popup = popup.replaceAll("\\{fly\\_stay\\_type\\_list\\}", getPopupStayTypeList(fly));
		popup = popup.replaceAll("\\{fly\\_stay\\_location\\_list\\}", getPopupStayLocationList(fly));

		SimpleDateFormat sdfDate = new SimpleDateFormat("yyyy/MM/dd");
		SimpleDateFormat sdfTime = new SimpleDateFormat("hh:mm");

		popup = popup.replaceAll("\\{dialog\\_fly\\_stay\\_start\\_date\\}", fly.getStayStart() == null ? "" : (sdfDate.format(fly.getStayStart())));
		popup = popup.replaceAll("\\{dialog\\_fly\\_stay\\_start\\_time\\}", fly.getStayStart() == null ? "" : (sdfTime.format(fly.getStayStart())));
		popup = popup.replaceAll("\\{dialog\\_fly\\_stay\\_end\\_date\\}", fly.getStayStart() == null ? "" : (sdfDate.format(fly.getStayEnd())));
		popup = popup.replaceAll("\\{dialog\\_fly\\_stay\\_end\\_time\\}", fly.getStayStart() == null ? "" : (sdfTime.format(fly.getStayEnd())));
		popup = popup.replaceAll("\\{fly\\_stay\\_comment\\}", fly.getStayStart() == null ? "" : (fly.getSaatsanComment()));

		popup = popup.replaceAll("\\{fly\\_done\\_value\\}", fly.isDone() ? "1" : "0");
		popup = popup.replaceAll("\\{fly\\_done\\_label\\}", fly.isDone() ? "Ниссэн" : "Нисээгүй");

		renderView(popup.toString(), response);
	}

	public String getPopupStayTypeList(Fly fly)
	{
		StringBuilder popup = new StringBuilder();
		for (FlyStayType flyStayType : FlyStayType.values())
		{
			String selected = fly.getFlyStayType() == null ? "" : (fly.getFlyStayType().equals(flyStayType) ? "selected=\"selected\"" : "");
			popup.append("<option " + selected + " value=\"" + flyStayType.name() + "\">" + flyStayType.getFlyStayType() + "</option>");
		}
		return popup.toString();
	}

	public String getPopupStayLocationList(Fly fly)
	{
		StringBuilder popup = new StringBuilder();
		@SuppressWarnings("unchecked")
		ArrayList<Location> locations = (ArrayList<Location>) getAllObjects(Location.class);
		for (Location location : locations)
		{
			String selected = fly.getStayLocation() == null ? "" : (fly.getStayLocation().getId() == location.getId() ? "selected=\"selected\"" : "");
			popup.append("<option " + selected + " value=\"" + location.getId() + "\">" + location.getName() + "</option>");
		}
		return popup.toString();
	}

	public String getAvailableEmployeeList(Fly fly, Session session)
	{
		String popup = "";
		boolean berlin = false;
		boolean category = true;
		if ( fly.getDstPosition().getId() == 8 )
			berlin = true;
		ArrayList<Employee> allEmployees = Employee.getAllEmployeeByFlyTimeASC(session, berlin, category);
		ArrayList<Employee> allAvailableStewards = Employee.getAvailableEmployee(session, allEmployees, fly, false, 0, false, false, 0);

		for (Employee employee : allAvailableStewards)
		{
			String willFlyTime = StaticMethods.formatFloat(employee.getWillFlyTimeOnThisMonth(false, null));
			popup += "<option value=\"" + employee.getId() + "\">" + employee.getName() + " " + willFlyTime + "</option>";
		}
		return popup;
	}

	public String getEmployees(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
	{
		long flyid = Long.parseLong(request.getParameter("flyid"));
		Fly fly = (Fly) getObjectByPk(Fly.class, flyid);
		String popup = "";
		int count = 1;
		for (Employee employee : Employee.getEmployeesByFly(getSession(), fly))
		{
			FlyEmployee flyEmployee = FlyEmployee.getFlyEmployeeByFlyAndEmployee(getSession(), fly, employee);
			String longDelayedCheck = flyEmployee.isBerlinLongDelay() ? "checked=\"checked\"" : "";

			popup += "<div style=\"width:100%; display:inline-block; vertical-align:middle; padding:5px;\">";
			popup += "<div id=\"name_text\">" + count + "." + employee.getName() + "</div>";
			popup += "<div style=\"font-size:11px; color:#183b75; width:50px; float:left\">" + StaticMethods.formatFloat(employee.getWillFlyTimeOnThisMonth(false, null)) + "</div>";
			if ( fly.getDstPosition().getId() == 8 )
				popup += "<div style=\"width:30px; float:left; margin-left:10px;\"><input type=\"checkbox\"" + longDelayedCheck + "/></div>";
			popup += "<div id=\"remove\" flyid=\"" + fly.getId() + "\" employeeid=\"" + employee.getId() + "\" style=\"cursor: pointer; background:url({path}images/delete.png) no-repeat; width:16px; height:16px; float:left; margin-left:15px\"></div>";
			popup += "</div>";
			count++;
		}
		popup = popup.replaceAll("\\{path\\}", StaticMethods.PATH);
		return popup;
	}

	public void removeEmployee(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
	{
		long flyid = Long.parseLong(request.getParameter("flyid"));
		Fly fly = (Fly) getObjectByPk(Fly.class, flyid);
		long employeeid = Long.parseLong(request.getParameter("employeeid"));
		Employee employee = (Employee) getObjectByPk(Employee.class, employeeid);

		Calculate.removeEmployeeFromFly(getSession(), fly, employee);

		getPopup(request, response);
	}

	public void addEmployee(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
	{
		Fly fly = (Fly) getObjectByPk(Fly.class, Long.parseLong(request.getParameter("flyid")));
		Employee employee = (Employee) getObjectByPk(Employee.class, Long.parseLong(request.getParameter("employeeid")));

		Transaction transaction = getSession().beginTransaction();
		Calculate.setEmployeeToFly(getSession(), fly, employee, true);
		transaction.commit();

		getPopup(request, response);
	}

	public String getYearList()
	{
		String year_lsit = "";
		int currentYear = Calendar.getInstance().get(Calendar.YEAR);
		for (int year : StaticMethods.getYearList(getSession()))
		{
			String selected = (currentYear == year) ? "selected=\"selected\"" : "";
			year_lsit += "<option " + selected + " value=\"" + year + "\">" + year + "</option>";
		}
		return year_lsit;
	}

	/**
	 * Нислэгийн саатал оруулах модуль.
	 * 
	 * @param request
	 * @param response
	 * @throws ServletException
	 * @throws IOException
	 */
	@SuppressWarnings("deprecation")
	public void saveFlyStay(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
	{
		Transaction transaction = getSession().beginTransaction();
		try
		{
			long flyid = Long.parseLong(request.getParameter("flyid"));
			Fly fly = (Fly) getObjectByPk(Fly.class, flyid);
			fly.setSaatsan(true);
			fly.setFlyStayType(FlyStayType.valueOf(request.getParameter("type")));
			fly.setStayStart(new Date(request.getParameter("start_date")));
			fly.setStayEnd(new Date(request.getParameter("end_date")));
			Location location = new Location();
			location.setId(Long.parseLong(request.getParameter("location")));
			fly.setStayLocation(location);
			fly.setSaatsanComment(getParameter("comment"));
			getSession().merge(fly);
			renderView("Нислэгийн саатал хадгалагдлаа.", response);
			
//			for (FlyEmployee flyEmployee: fly.getFlyEmployees()){
//				Stay stay = new Stay();
//				stay.setEmployee(flyEmployee.getEmployee());
//				stay.setStayType(StayType.DELAY);
//				stay.setStart(fly.getStayStart());
//				stay.setEnd(fly.getStayEnd());
//				stay.setComment(fly.getSaatsanComment());
//				stay.setLocation(fly.getStayLocation());
//				getSession().save(stay);
//			}
			
			transaction.commit();
		}
		catch (HibernateException exception)
		{
			exception.printStackTrace();
			if ( transaction != null )
				transaction.rollback();
			renderView("Нислэгийн саатал хадгалагдаж чадсангүй!", response);
		}
	}

	/**
	 * Нислэг амжилттай дууссан эсэхийг тодорхойлох үед ажаксаар дуудагдна.
	 * 
	 * @param
	 * @param response
	 * @throws ServletException
	 * @throws IOException
	 */
	public void doneFly(HttpServletRequest request, HttpServletResponse response)
	{
		Transaction transaction = getSession().beginTransaction();
		try
		{
			long flyid = Long.parseLong(request.getParameter("flyid"));
			boolean done = request.getParameter("done").equals("1") ? true : false;
			Fly fly = (Fly) getObjectByPk(Fly.class, flyid);
			fly.setDone(!done);
			getSession().merge(fly);
			transaction.commit();
			if ( fly.isDone() )
			{
				renderView("<input id=\"btn_fly_done\" done-value=\"1\" class=\"btn_div\" type=\"button\" value=\"Ниссэн\"/>", response);
			}
			else
			{
				renderView("<input id=\"btn_fly_done\" done-value=\"0\" class=\"btn_div\" type=\"button\" value=\"Нисээгүй\"/>", response);
			}
		}
		catch (Exception exception)
		{
			exception.printStackTrace();
			if ( transaction != null )
				transaction.rollback();
		}
	}
	public void alertPopup(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{
		renderView("хүн дутуу");
	}
}